﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TestMySqlConnetPoll;
using System.Threading;
using DevExpress.Skins;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;

namespace View.Table
{
    public partial class HistorySwitch : Form
    {
        List<kglstruct> source = new List<kglstruct>();
        Dictionary<int, List<kglstruct>> sourceDic = new Dictionary<int, List<kglstruct>>();
        KGL_Table kgltable;
        int NowPlayTime = 0;
        int speed = 1;
        int startTime = 0;
        int endTime = 0;
        public HistorySwitch()
        {
            InitializeComponent();
            InitTable();
            this.gridControl1.DataSource = source;
            this.gridView1.BestFitColumns();
            kgltable = new KGL_Table();
            btn_start.Enabled = false;
            btn_stop.Enabled = false;
            btn_speed.Enabled = false;
            btn_dn.Enabled = false;
            dateTimePicker1.Value = DateTime.Now.AddMinutes(-30);
            textBox1.Text = "30";
        }

        private void InitTable()
        {            
            for (int i = 0; i < c_Device.KGL_Config.Count; i++)
            {
                kglstruct kgl = new kglstruct();
                kgl.kglName = c_Device.KGL_Config[i].Name;
                kgl.fjNo = c_Device.KGL_Config[i].FeiJiNo.ToString();
                kgl.statue = "↓";
                kgl.type = c_Device.KGL_Config[i].SourceFlag;
                string s = ""; string ss = "";
                c_Device.GetKGLInMsgGather(i, ref s, ref ss);
                kgl.MsgName = s;
                kgl.DevName = ss;
                kgl.BHflag = "0";
                source.Add(kgl);
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }

        private void FillData()
        {
            sourceDic.Clear();
            int key = startTime;
            for (int i = 0; i < (endTime-startTime); i++)
            {
                List<kglstruct> li = new List<kglstruct>();
                for (int j = 0; j < c_Device.KGL_Config.Count; j++)
                {
                    kglstruct kgl = new kglstruct();
                    kgl.kglName = c_Device.KGL_Config[j].Name;
                    kgl.fjNo = c_Device.KGL_Config[j].FeiJiNo.ToString();
                    kgl.statue = GetReplayKGLValue(NowPlayTime, j);
                    kgl.type = c_Device.KGL_Config[j].SourceFlag;
                    string s = ""; string ss = "";
                    c_Device.GetKGLInMsgGather(j, ref s, ref ss);
                    kgl.MsgName = s;
                    kgl.DevName = ss;
                    kgl.BHflag = "0";
                    li.Add(kgl);
                }
                sourceDic.Add(key, li);
                key++;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if(textBox1.Text != ""&& (int.Parse(textBox1.Text)<=60))
            {

            }
            else
            {
                MessageBox.Show("请输入正确的时长，最长不超过60分钟");
                return;
            }
            DateTime stime = dateTimePicker1.Value;
            DateTime etime = stime.AddMinutes(int.Parse(textBox1.Text));
            kgltable.Read_KGL_ValueList(MySql.DateTimeToTime_t(stime), MySql.DateTimeToTime_t(etime));
            while(!kgltable.Ready_KGL_ValueList)
            {
                if (kgltable.ErrorFlag != 0) break;
                else
                    Thread.Sleep(20);
            }
            if (kgltable.ErrorFlag > 0) MessageBox.Show("获取开关量数据错误");
            else if (kgltable.KGL_ValueList.Count == 0) MessageBox.Show("该段时间无开关量数据");
            if(kgltable.KGL_ValueList.Count>0)
            {
                btn_start.Enabled = true;
                label_bv.Text = "×1";
                speed = 1;
                label_time.Text = MySql.Time_tToDateTime(kgltable.KGL_ValueList[0].u_time).ToString();
                NowPlayTime = kgltable.KGL_ValueList[0].u_time;
                startTime = NowPlayTime;
                endTime = MySql.DateTimeToTime_t(etime);
                label_endTime.Text = etime.ToString();
                int freq =(int)etime.Subtract(stime).TotalSeconds;
                trackBar1.Value = 0;
                trackBar1.SetRange(0, freq);
                trackBar1.TickFrequency = (freq);
                trackBar1.SmallChange = 5;
                trackBar1.LargeChange = 10;
                timer1.Interval = 1000;
                //FillData();
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)13 && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
        }

        private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
        {

        }

        /// <summary>
        /// 取单个开关量一秒内的变化值，用于回放时的开关量表格显示. 一秒内可能变化多次
        /// </summary>
        /// <param name="utime"></param>
        /// <param name="devNo"></param>
        /// <returns></returns>
        public string GetReplayKGLValue(int utime, int devNo)
        {
            string rets = "";
            string mids = "";
            for (int i = 0; i < kgltable.KGL_ValueList.Count; i++)
            {
                ObjKGL obj = kgltable.KGL_ValueList[i];
                if (obj.type == 1)    //全体开关量
                {
                    if (obj.u_time < utime) //取最接近的一包全体开关量的值
                    {
                        int x = devNo / 8;
                        if (devNo % 8 != 0) x++;
                        int y = (devNo % 8);
                        if (x < obj.len)
                        {
                            int tt = ((obj.v[x] >> y) & 0x01);
                            if (tt == 1) mids = "↑";
                            else mids = "↓";
                        }
                    }
                    else if (obj.u_time == utime)
                    {
                        int x = devNo / 8;
                        if (devNo % 8 != 0) x++;
                        int y = (devNo % 8);
                        if (x < obj.len)
                        {
                            int tt = ((obj.v[x] >> y) & 0x01);
                            if (tt == 1) mids = " ↑ ";
                            else mids = " ↓ ";
                            rets = rets + mids;
                        }
                    }
                    else
                    {
                        if (rets == "") //只有没找到全部时间相等的全体，才取上一包全体
                        {
                            rets = mids;
                        }
                        return rets;
                    }
                }
                else if (obj.type == 0) //变化开关量
                {
                    for (int j = 0; j < obj.len; j++)
                    {
                        int ttime = obj.v[j] + (obj.v[j + 1] << 8) + (obj.v[j + 2] << 16) + (obj.v[j + 3] << 24);
                        j += 4;
                        int no = obj.v[j] + (obj.v[j + 1] << 8);
                        j += 2;
                        byte s = (byte)(no >> 15);
                        no = no & 0x7fff;
                        if (ttime == utime)  //取最接近的一包变化开关量的值。
                        {
                            if (no == devNo)
                            {
                                if (s == 1) rets = rets + " ↑ ";
                                else rets = rets + " ↓ ";
                            }
                        }
                        if (ttime > utime) return rets;
                    }
                }
            }
            return rets;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.gridView1.BeginUpdate();
            for (int i = 0; i < source.Count; i++)
            {
                source[i].statue = GetReplayKGLValue(NowPlayTime, i);
            }
            this.gridView1.EndUpdate();
            label_time.Text = MySql.Time_tToDateTime(NowPlayTime).ToString();

            if (trackBar1.Value < trackBar1.Maximum)
                trackBar1.Value++;
            if (NowPlayTime >= endTime) timer1.Stop();
            else NowPlayTime++;
        }

        private void btn_start_Click(object sender, EventArgs e)
        {
            timer1.Start();
            btn_stop.Enabled = true;
            btn_speed.Enabled = true;
            btn_dn.Enabled = true;
        }

        private void btn_speed_Click(object sender, EventArgs e)
        {
            if (speed < 8)
            {
                timer1.Interval = 1000 / speed;
                speed++;
                label_bv.Text = "×" + speed.ToString();
            }
            else btn_speed.Enabled = false;
            btn_dn.Enabled = true;
        }

        private void btn_dn_Click(object sender, EventArgs e)
        {
            if (speed > 1)
            {
                speed--;
                timer1.Interval = 1000 / speed;
            }
            else btn_dn.Enabled = false;
            btn_speed.Enabled = true;
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            NowPlayTime = startTime + trackBar1.Value;
        }

        private void barCheckItem1_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (barCheckCSM.Checked == true)
            {
                col_Csm.Group();
                barCheckDev.Checked = false;
                barChecktype.Checked = false;
            }
            else col_Csm.UnGroup();
        }

        private void barCheckDev_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (barCheckDev.Checked == true)
            {
                col_DevName.Group();
                barCheckCSM.Checked = false;
                barChecktype.Checked = false;
            }
            else col_DevName.UnGroup();
        }

        private void barChecktype_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (barChecktype.Checked)
            {
                col_type.Group();
                barCheckCSM.Checked = false;
                barCheckDev.Checked = false;
            }
            else col_type.UnGroup();
        }

        private void gridView1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.Info.IsRowIndicator && e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString().Trim();
            }
        }

        private void gridView1_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
        {
            string val = gridView1.GetRowCellValue(e.RowHandle, "状态") as string;
            GridCellInfo cell = e.Cell as GridCellInfo;
            if (cell.Column.Caption == "状态" && e.RowHandle > 0)
            {
                if (source[e.RowHandle].statue.Contains("↑"))
                {
                    cell.Appearance.ForeColor = CommonColors.GetCriticalColor(DevExpress.LookAndFeel.UserLookAndFeel.Default);
                }
            }
        }
    }
}

